// 导入Vue的响应式引用类型和计算属性类型
import type { ComputedRef, Ref } from 'vue';
// 导入表单相关的类型定义
import type { FormProps, FormSchema, FormActionType } from '../types/form';
// 导入Vue的unref和toRaw函数，用于处理响应式引用
import { unref, toRaw } from 'vue';
// 导入类型判断工具函数
import { isDef, isFunction } from '@/utils/is';

// 声明EmitType类型，用于定义emit函数的类型
declare type EmitType = (event: string, ...args: any[]) => void;

// 定义UseFormActionContext接口，包含表单操作所需的上下文
interface UseFormActionContext {
  emit: EmitType; // 用于触发事件的函数
  getProps: ComputedRef<FormProps>; // 获取表单属性的计算属性
  getSchema: ComputedRef<FormSchema[]>; // 获取表单schema的计算属性
  formModel: Recordable; // 表单模型
  formElRef: Ref<FormActionType>; // 表单元素的响应式引用
  defaultFormModel: Recordable; // 默认表单模型
  loadingSub: Ref<boolean>; // 加载子状态的响应式引用
  handleFormValues: Function; // 处理表单值的函数
}

// useFormEvents函数，用于处理表单事件
export function useFormEvents({
  emit,
  getProps,
  formModel,
  getSchema,
  formElRef,
  defaultFormModel,
  loadingSub,
  handleFormValues,
}: UseFormActionContext) {
  // 验证表单
  async function validate() {
    return unref(formElRef)?.validate();
  }

  // 提交表单
  async function handleSubmit(e?: Event): Promise<object | boolean> {
    e && e.preventDefault(); // 阻止默认事件
    loadingSub.value = true; // 设置加载状态为true
    const { submitFunc } = unref(getProps); // 获取提交函数
    if (submitFunc && isFunction(submitFunc)) {
      await submitFunc(); // 执行提交函数
      loadingSub.value = false; // 设置加载状态为false
      return false;
    }
    const formEl = unref(formElRef); // 获取表单元素
    if (!formEl) return false;
    try {
      await validate(); // 验证表单
      const values = getFieldsValue(); // 获取表单值
      loadingSub.value = false; // 设置加载状态为false
      emit('submit', values); // 触发submit事件
      return values;
    } catch (error: any) {
      emit('submit', false); // 触发submit事件，传入false
      loadingSub.value = false; // 设置加载状态为false
      console.error(error); // 打印错误信息
      return false;
    }
  }

  // 清空表单校验
  async function clearValidate() {
    await unref(formElRef)?.resetFields();
  }

  // 重置表单
  async function resetFields(): Promise<void> {
    const { resetFunc, submitOnReset } = unref(getProps); // 获取重置函数和提交重置属性
    resetFunc && isFunction(resetFunc) && (await resetFunc()); // 执行重置函数
    const formEl = unref(formElRef); // 获取表单元素
    if (!formEl) return;
    Object.keys(formModel).forEach((key) => {
      formModel[key] = unref(defaultFormModel)[key] || null; // 重置表单模型
    });
    await clearValidate(); // 清空校验
    const fromValues = handleFormValues(toRaw(unref(formModel))); // 处理表单值
    emit('reset', fromValues); // 触发reset事件
    submitOnReset && (await handleSubmit()); // 如果需要，在重置后提交表单
  }

  // 获取表单值
  function getFieldsValue(): Recordable {
    const formEl = unref(formElRef); // 获取表单元素
    if (!formEl) return {};
    return handleFormValues(toRaw(unref(formModel))); // 处理并返回表单值
  }

  // 设置表单字段值
  function setFieldsValue(values: Recordable): void {
    const fields = unref(getSchema) // 获取schema字段
      .map((item) => item.field)
      .filter(Boolean);
    // 支持嵌套字段写法，如 a.b.c
    const decimal = '.';
    const decimalKeyList = fields.filter((item) => item.indexOf(decimal) >= 0);
    Object.keys(values).forEach((key) => {
      const value = values[key];
      const isKey = Reflect.has(values, key);
      if (isKey && fields.includes(key)) {
        formModel[key] = value; // 设置表单模型的值
      } else {
        decimalKeyList.forEach((itemKey: string) => {
          try {
            const value = eval('values' + decimal + itemKey); // 使用eval获取嵌套值
            if (isDef(value)) {
              formModel[itemKey] = value; // 设置表单模型的值
            }
          } catch (e) {
            console.error(e); // 打印错误信息
          }
        });
      }
    });
  }

  // 设置加载子状态
  function setLoadingSub(value: boolean): void {
    loadingSub.value = value; // 设置加载状态
  }

  // 返回表单事件处理函数
  return {
    handleSubmit,
    validate,
    resetFields,
    getFieldsValue,
    clearValidate,
    setFieldsValue,
    setLoadingSub,
  };
}
